#pragma once 

#include <string>
#include <Peer/Peer2Peer-Peer/P2pPeer.h>
#include <Peer/AbstractPeer.h>
#include <ObservableEvents/ObservableEventsList/ObservaleEventsList.h>

#include "../ObservableEventsMonitor/ICUpdatesMonitor.h"
#include "../ObservableEventsList/ICObservableEventsList.h"
#include "../../Integrators/RadianceDetails/RadiancePoint.h"

using namespace Network::Peer;
using namespace Engine::Networking::Monitor;
using std::string;
namespace Engine
{
	namespace Networking
	{
		///-------------------------------------------------------------------------------------------------
		/// <summary>	A peer initializer. </summary>
		///
		/// <remarks>	Adrian, 24/09/2015. </remarks>
		///-------------------------------------------------------------------------------------------------
		template<typename T, typename S>
		class PeerInitializer
		{
		public:
			AbstarctPeer<T,S>* InitializePeer(int p_amountPeers,string p_ipAddress, int p_socketNumber, int p_sequenceNumber, string p_nameAssigned, int p_peerIndex, IrradianceCache* p_Ic, float p_fltSleepAfterComm = 2.0f, float p_fltSleepAfterFailedComm = 2.0f , bool p_monitoringMode = true)
			{
				m_observableEventsList = new Engine::Networking::ObservableEvents::ICObservableEventsList(p_peerIndex,p_amountPeers,p_Ic);
				m_peer = new P2pPeer<T,S>(p_ipAddress, p_socketNumber, p_sequenceNumber, p_nameAssigned, m_observableEventsList, p_amountPeers, p_fltSleepAfterComm, p_fltSleepAfterFailedComm);
				m_monitor = new UpdateMonitor<>(m_peer, p_Ic, m_observableEventsList,200, true);
				
				
				return m_peer;
			}

			ObservableEventsList<T,S>* GetObservableEventsList()
			{
				return m_observableEventsList;
			}

			AbstarctPeer<T,S>* GetPeer()
			{
				return m_peer;
			}

			UpdateMonitor<T>* GetMonitor()
			{
				return m_monitor;
			}

			bool IsIpSet()
			{
				return m_peer->ipSet;
			}

			string GetIpAddress()
			{
				return m_peer->m_ipAddress
			}

		private:
			ObservableEventsList<T,S>* m_observableEventsList;
			AbstarctPeer<T,S>* m_peer;
			UpdateMonitor<T>* m_monitor;
			string p_peerData;
		};
	}
}
